package service

import (
	"context"
	"fmt"
	"gitee.com/filters/logger"
	"gitee.com/filters/starter/config"
	"gitee.com/filters/utils/conversion"
	"github.com/gin-gonic/gin"
	"github.com/robfig/cron/v3"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"log"
	"net/http"
	"reflect"
)

type GrpcHttpServer struct {
	*GrpcServer
	*GinServer
	*grpc.ClientConn
}

func NewGrpcHttp(cfgMap []GrpcCfgMap) *GrpcHttpServer {
	g := &GrpcHttpServer{
		GrpcServer: NewGrpc(cfgMap),
		GinServer:  NewGin(),
	}
	return g
}

// UseLog 日志记录
func (g *GrpcHttpServer) UseLog() *GrpcHttpServer {
	var logx config.GinLog
	if err := g.GinServer.GetConfig().UnmarshalKey(logger.Logger, &logx); err != nil {
		panic(err)
	}
	logger.NewLog(logger.WithWritePath(logx.LogFilePath),
		logger.WithLogExt(logx.LogFileExt)).CurLog().WrapFormat()
	return g
}

// BindField 绑定数据
func (g *GrpcHttpServer) BindField(f ...interface{}) *GrpcHttpServer {
	for _, i2 := range f {
		conversion.ToStruct(g.GinServer.GetConfig().AllSettings(), i2)
	}
	return g
}

// HandleMiddleware 绑定中间件
func (g *GrpcHttpServer) HandleMiddleware(middles ...gin.HandlerFunc) *GrpcHttpServer {
	g.GinServer.GetEs().Use(middles...)
	return g
}

// HandleAddFunc 定时执行函数
func (g *GrpcHttpServer) HandleAddFunc(list []*config.CronTabObj) *GrpcHttpServer {
	c := cron.New(cron.WithSeconds())
	for index, crontabObj := range list {
		func(id int, obj *config.CronTabObj) {
			_, _ = c.AddJob(
				obj.CronTab, //一分钟
				cron.FuncJob(func() {
					_ = obj.Handler()
				}))
		}(index, crontabObj)
	}
	c.Start() //启动crond
	return g
}

// HandleRouter 绑定路由
func (g *GrpcHttpServer) HandleRouter(route func(r *gin.Engine)) *GrpcHttpServer {
	route(g.GinServer.GetEs())
	return g
}
func (g *GrpcHttpServer) Run() error {

	go func() {
		g.GrpcServer.Run()
	}()
	g.GinServer.GetEs().GET("/hello", SayHello)
	g.GinServer.Run()
	return nil
}

func (g *GrpcHttpServer) createClient() {
	conn, err := grpc.Dial(fmt.Sprintf("http://127.0.0.1:%d", g.GetGrpcConfig().GrpcPort), grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	for _, v := range g.GrpcServer.GetMap() {
		ss := reflect.ValueOf(v.Srv)
		args := []reflect.Value{reflect.ValueOf(conn)}
		ss.Call(args)
	}
	g.ClientConn = g.GrpcServer.GetMap()[0].Srv(conn)
}
func SayHello(c *gin.Context) {
	name := c.Param("name")

	resp, err := h.grpcClient.SayHello(context.Background(), &example.HelloRequest{
		Name: name,
	})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": resp.Message})
}
